'''
查看图片


下一张： 空格
上一张： B
放大：ctrl + 滚轮
平移：ctrl + 左键拖动
'''
import glob

import sys
import traceback

import cv2
import numpy
import numpy as np
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QComboBox
from PyQt5.QtCore import Qt, QRectF, QPointF, QLineF
from PyQt5.QtGui import QPainter, QPixmap, QImage, QPen, QColor, QFont, QCursor

# from log import saved_algo_param_dict #
saved_algo_param_dict = {}


def array2pix(image, ismask=False):
    if len(image.shape) == 2:
        image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGRA)

    if image.shape[2] == 1:
        image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGRA)

    if image.shape[2] == 3:
        # image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)
    # show1 = cv2.resize(image, (640, 480))
    if ismask:
        # image[:,:,3] = image[:,:,2]
        pass

    show1 = image
    # QtImg = QImage(show1.data, show1.shape[1], show1.shape[0], QImage.Format_BGR888)
    QtImg = QImage(
        show1.data, show1.shape[1], show1.shape[0], QImage.Format_ARGB32)
    pixmap = QPixmap(QtImg)
    return pixmap


class ImageWithResizableBox(QWidget):
    def __init__(self, test_config):
        '''

        :param imagePath:
        :param default_threshold_list: 电线高度 px; 相机中心点 px px，距离 px，角度 degree；
        '''
        super().__init__()

        self.target_dict = test_config.get('target_dict')  # fileind: {modelname:{'show_img':_,'val_show_img':_}}
        # self.target_dict = {'622': {'20250618141520_detr-r101-dc5_800_traindata580': {
        #     'show_img': 'D:\\DATA\\20250611HKBZ\\temp\\20250618141520_detr-r101-dc5_800_traindata580\\show_img\\622.jpg',
        #     'val_show_img': 'D:\\DATA\\20250611HKBZ\\temp\\20250618141520_detr-r101-dc5_800_traindata580\\val_show_img\\622.jpg'}},
        #     '624': {'20250618141520_detr-r101-dc5_800_traindata580': {
        #         'show_img': 'D:\\DATA\\20250611HKBZ\\temp\\20250618141520_detr-r101-dc5_800_traindata580\\show_img\\624.jpg',
        #         'val_show_img': 'D:\\DATA\\20250611HKBZ\\temp\\20250618141520_detr-r101-dc5_800_traindata580\\val_show_img\\624.jpg'}},
        # }
        self.origin_scale = test_config.get('origin_scale', 0.5)

        # self.img_glob_str = test_config.get('target_dict')

        # self.file_inds = glob.glob(self.img_glob_str)
        self.file_inds = list(self.target_dict.keys())
        self.img_index = 0

        self.setFocusPolicy(Qt.StrongFocus)
        self.setFocus()
        self.is_ctrl_pressed = False  # ctrl 按下

        self.load_img_annotator()

    def load_img_annotator(self):
        # 接下来是加载新图像和标注的逻辑 ...
        self.file_ind = self.file_inds[self.img_index]

        # 根据file_ind 画图 输出拼接图
        file_ind_dict = self.target_dict[self.file_ind]  # n模型* 2类别（valshow,show）
        # img_counts = len(file_ind_dict.keys())
        # if img_counts > 4:
        #     raise Exception(f'img_counts {img_counts} > 4')
        img_clips = []
        img_names = []
        for model_name, img_dict in file_ind_dict.items():
            val_show_path = img_dict['val_show_img']
            img_clip = cv2.imread(val_show_path)
            px = img_clip.shape[1] // 15
            py = img_clip.shape[0] // 15
            cv2.putText(img_clip, model_name, (px, py), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 4) # 画
            img_clips.append(img_clip)
            img_names.append(model_name)
        show_img = None
        if len(img_clips) == 1:
            show_img = img_clips[0]
            # px = show_img.shape[1] // 2
            # py = show_img.shape[0] // 15
            # cv2.putText(show_img, f'{img_names[0]}', (px, py), cv2.FONT_HERSHEY_COMPLEX_SMALL, 4, (0, 255, 0), 4)
        elif len(img_clips) == 2:
            show_img = np.vstack(img_clips)
            # px = show_img.shape[1] // 10
            # py = show_img.shape[0] // 15
            # cv2.putText(show_img, f'{img_names[0]}/{img_names[1]}', (px, py), cv2.FONT_HERSHEY_COMPLEX_SMALL, 4,
            #             (0, 255, 0), 4)

        # 设置图片
        self.orig_pixmap = array2pix(show_img)  # 备份，用于缩放
        self.chk_scaleimg_x1, self.chk_scaleimg_y1 = 0, 0  # 图片左上角 相对窗口坐标系
        self.scale = self.origin_scale
        self.orig_img_height, self.orig_img_width = self.orig_pixmap.height(), self.orig_pixmap.width()
        self.current_pixmap = self.orig_pixmap.scaled(int(self.orig_pixmap.width() * self.scale),
                                                      int(self.orig_pixmap.height() * self.scale), Qt.KeepAspectRatio,
                                                      Qt.SmoothTransformation)  # 当前的pixmap

        window_title = f'{self.img_index + 1}/{len(self.file_inds)}  {self.file_inds[self.img_index]}.jpg  '
        self.setWindowTitle(window_title)
        self.resize(self.current_pixmap.width(), self.current_pixmap.height())  # 调整窗口大小以适应图片

        self.update()

    def paintEvent(self, event):
        try:
            print('paintEvent')
            window_title = f'{self.img_index + 1}/{len(self.file_inds)}  {self.file_inds[self.img_index]}.jpg '
            # self.resize(self.current_pixmap.width(), self.current_pixmap.height())  # 调整窗口大小以适应图片
            painter = QPainter(self)
            painter.drawPixmap(self.chk_scaleimg_x1, self.chk_scaleimg_y1, self.current_pixmap)  # 画图 x1y1
            # painter.drawPixmap(-100, -300, self.current_pixmap)  # 画图 x1y1

            self.setWindowTitle(window_title)

        except:
            print(traceback.format_exc())

    def mouseDoubleClickEvent(self, event):
        self.update()

    def mousePressEvent(self, event):  # 鼠标按下
        try:
            print('mousePressEvent')
            if event.button() == Qt.LeftButton:

                if self.is_ctrl_pressed:
                    # 平移图片
                    self.last_mouse_globalpos = event.globalPos()
                    return


        except:
            print(traceback.format_exc())

    def mouseMoveEvent(self, event):  # 鼠标移动
        try:
            print('mouseMoveEvent')

            if self.is_ctrl_pressed:
                # # 平移图片
                global_pos = event.globalPos()
                dx = global_pos.x() - self.last_mouse_globalpos.x()
                dy = global_pos.y() - self.last_mouse_globalpos.y()

                self.chk_scaleimg_x1 += dx
                self.chk_scaleimg_y1 += dy  # update()里更新显示图片

                self.last_mouse_globalpos = global_pos
                self.update()
                return

            self.update()  # 执行paintEvent()
        except:
            print(traceback.format_exc())

    def mouseReleaseEvent(self, event):  # 鼠标释放
        try:
            print('mouseReleaseEvent')

            self.setCursor(QCursor(Qt.ArrowCursor))  # 默认箭头
            # self.update_annonation()
            self.update()
        except:
            print(traceback.format_exc())

    def wheelEvent(self, event):  # 鼠标滚动
        try:
            print('wheelEvent')
            if not self.is_ctrl_pressed:
                return

            print(event.angleDelta().x())
            print(event.angleDelta().y())  # 120 -120
            print(event.globalPos())  # 全局坐标 屏幕？
            print(event.pos())  # 局部坐标 窗口？

            # 1 以鼠标为原点 缩放图像
            pre_scale = self.scale
            step_len = 0.05 * self.scale * event.angleDelta().y() / 120 * 5
            print(f'step_len {step_len}')
            # self.scale = self.scale*self.scale/self.orig_scale*event.angleDelta().y() / 120
            self.scale = self.scale + step_len  # 1%
            chk_shb_x, chk_shb_y = event.pos().x(), event.pos().y()  # 相对窗口坐标系 鼠标坐标

            tx_shb_x, tx_shb_y = (chk_shb_x - self.chk_scaleimg_x1), (
                    chk_shb_y - self.chk_scaleimg_y1)  # 计算图像左上角 相对窗口坐标系
            self.chk_scaleimg_x1 = self.chk_scaleimg_x1 - step_len * tx_shb_x / pre_scale
            self.chk_scaleimg_y1 = self.chk_scaleimg_y1 - step_len * tx_shb_y / pre_scale  # 平移

            # 缩放图片
            self.current_pixmap = self.orig_pixmap.scaled(int(self.orig_img_width * self.scale),
                                                          int(self.orig_img_height * self.scale),
                                                          Qt.KeepAspectRatio, Qt.SmoothTransformation)

            self.update()  # paintEvent

        except:
            print(traceback.format_exc())

    def closeEvent(self, event):
        # saved_algo_param_dict['step1'] = []
        pass

    def keyPressEvent(self, event):  # 键盘按下事件
        print('keyPressEvent')
        try:

            if event.key() == Qt.Key_Space:  # 跳转下一张图片
                # self.update_annonation()
                self.img_index = (self.img_index + 1) % len(self.file_inds)
                self.load_img_annotator()
                print()


            elif event.key() == Qt.Key_B:  #

                self.img_index = (self.img_index - 1) % len(self.file_inds)
                self.load_img_annotator()

            elif event.key() == Qt.Key_Control:  # ctrl
                self.is_ctrl_pressed = True
        except:
            print(traceback.format_exc())

    def keyReleaseEvent(self, event):  # 键盘释放事件
        print('keyReleaseEvent')
        if event.key() == Qt.Key_Control:  # ctrl
            self.is_ctrl_pressed = False
            pass


if __name__ == "__main__":

    app = QApplication(sys.argv)
    # img_glob = r"D:\DATA\20250519RENBAO\temp\annotated\*.jpg"
    # img_glob = r"D:\DATA\20250519RENBAO\trainV8Pose_people\add_imgs\test10\*.jpg"
    # img_glob = r'D:\DATA\20250519RENBAO\caitu\20250527_annotated_100_200\*.jpg'

    test_config = {
        'img_glob': r'D:\DATA\20250519RENBAO\temp\20250609102346_mid_cam_t23725-2025-05-13_16-48-43.mp4_frames\annotated\*.jpg',
        'origin_scale': 0.5,
    }

    try:
        # widget = ImageWithResizableBox(img_path)  # 替换为初始图片路径
        widget = ImageWithResizableBox(test_config)  # 替换为初始图片路径
        print("初始图片路径:", test_config['img_glob'])
    except:
        print(traceback.format_exc())
    widget.resize(widget.current_pixmap.width(), widget.current_pixmap.height())  # 调整窗口大小以适应图片
    widget.show()
    sys.exit(app.exec_())
